{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::optional` 的典型场景与优势\n",
    "\n",
    "**典型场景：**\n",
    "\n",
    "- 函数可能“无返回值”时的显式表达，例如查找、解析失败等。\n",
    "- 延迟初始化：成员可能不存在时。\n",
    "- 替代指针或特定错误码的返回值。\n",
    "\n",
    "**优势：**\n",
    "\n",
    "- 明确表示“有/无值”，可与 `has_value()` / `operator bool()` 配合使用，避免误读空指针。\n",
    "- 不需要额外的 sentinel 值或错误码，减少魔法常量。\n",
    "- 内部值直接存储，避免动态分配；比裸指针更安全，生命周期明确。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Age: 30\n"
     ]
    }
   ],
   "source": [
    "#include <optional>\n",
    "#include <iostream>\n",
    "#include <string>\n",
    "\n",
    "std::optional<int> find_age(const std::string& name) {\n",
    "    if (name == \"Alice\") return 30;\n",
    "    return std::nullopt;\n",
    "}\n",
    "\n",
    "{\n",
    "    if (auto age = find_age(\"Alice\")) {\n",
    "        std::cout << \"Age: \" << *age << '\\n';\n",
    "    } else {\n",
    "        std::cout << \"Unknown\\n\";\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::variant` 与 `std::visit`\n",
    "\n",
    "**访问方式：**\n",
    "\n",
    "- 使用 `std::get<T>` 或 `std::get<N>` 获取当前持有类型的值；若类型不匹配会抛 `std::bad_variant_access`。\n",
    "- 使用 `std::visit` 对 variant 内容执行多态行为。\n",
    "\n",
    "**`std::visit` 要求：**\n",
    "\n",
    "- 需要调用者提供可调用对象，其 `operator()` 必须对所有可能持有的类型可调用（或在通配中处理）。\n",
    "- 可组合多个 lambda（C++20 结构化 `overloaded`）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "holding: hello\n"
     ]
    }
   ],
   "source": [
    "#include <iostream>\n",
    "#include <variant>\n",
    "\n",
    "{\n",
    "    std::variant<int, std::string> v = \"hello\";\n",
    "\n",
    "    std::visit([](auto&& value) {\n",
    "        std::cout << \"holding: \" << value << '\\n';\n",
    "    }, v);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::any` 的用途与相对 `void*` 的优势\n",
    "\n",
    "**用途：**\n",
    "\n",
    "- 存放任意类型的值（类型擦除），在运行时进行类型检查。\n",
    "- 适合需要容纳多种未知类型但不想使用模板的容器或接口。\n",
    "\n",
    "**相对 `void*` 的优势：**\n",
    "\n",
    "- `std::any` 记录动态类型信息，可通过 `std::any_cast` 安全取回（失败抛异常或返回空指针）。\n",
    "- 自动管理对象生命周期，避免手动 delete。\n",
    "- 避免类型不匹配导致 UB。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "42\n"
     ]
    }
   ],
   "source": [
    "#include <any>\n",
    "#include <iostream>\n",
    "\n",
    "{\n",
    "    std::any value = 42;\n",
    "    try {\n",
    "        std::cout << std::any_cast<int>(value) << '\\n';\n",
    "    } catch (const std::bad_any_cast& e) {\n",
    "        std::cout << e.what() << '\\n';\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 结构化绑定（structured bindings）\n",
    "\n",
    "**语法：**\n",
    "\n",
    "```cpp\n",
    "auto [a, b, c] = some_tuple_like;\n",
    "```\n",
    "\n",
    "**解包规则：**\n",
    "\n",
    "- 可用于数组、`std::tuple`/`std::pair`、支持 `get<N>` 接口的类型、或公开成员的聚合类。\n",
    "- 声明的变量默认为 `auto` 推导，可加 `const`、`&`、`&&` 等修饰。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1, 3.14, pi\n"
     ]
    }
   ],
   "source": [
    "#include <tuple>\n",
    "#include <iostream>\n",
    "\n",
    "{\n",
    "    std::tuple<int, double, std::string> t{1, 3.14, \"pi\"};\n",
    "    auto [i, d, s] = t;\n",
    "    std::cout << i << \", \" << d << \", \" << s << '\\n';\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::string_view` 与 `std::string` 的差异\n",
    "\n",
    "- `std::string_view` 是对现有字符序列的**非拥有**视图：仅保存指针 + 长度，不拷贝数据。\n",
    "- **生命周期**：调用者必须确保原始数据在视图使用期间有效；`std::string` 拥有自己的缓冲区。\n",
    "- 单纯读取、切片等操作时可减少内存分配和拷贝。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "hello\n"
     ]
    }
   ],
   "source": [
    "#include <iostream>\n",
    "#include <string_view>\n",
    "\n",
    "void print(std::string_view sv) {\n",
    "    std::cout << sv << '\\n';\n",
    "}\n",
    "\n",
    "{\n",
    "    std::string s = \"hello world\";\n",
    "    print(s.substr(0, 5));       // substr 返回 string -> 拷贝\n",
    "    print(std::string_view{s}.substr(0, 5)); // 仅视图\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::filesystem` 常用操作与安全遍历\n",
    "\n",
    "**常用操作：**\n",
    "\n",
    "- 路径管理：`std::filesystem::path`\n",
    "- 文件状态：`exists`, `is_regular_file`, `file_size`\n",
    "- 创建/删除：`create_directory`, `remove_all`\n",
    "- 遍历：`directory_iterator`, `recursive_directory_iterator`\n",
    "- 复制/移动：`copy`, `rename`\n",
    "\n",
    "**安全遍历：**\n",
    "\n",
    "- 在访问前检查 `is_directory`，捕获 `std::filesystem::filesystem_error` 以处理权限问题。\n",
    "- 使用 `directory_iterator` 固定遍历深度，或 `recursive_directory_iterator` 并结合 `options` 处理符号链接。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\"./C++ 虚函数指针（vptr）总结.md\"\n",
      "\"./container.ipynb\"\n",
      "\"./基础类型与内存布局.ipynb\"\n",
      "\"./总结C++内存对齐.md\"\n",
      "\"./构造_析构期间调用虚函数.md\"\n",
      "\"./标准库与语言特性.ipynb\"\n",
      "\"./模板与泛型编程.ipynb\"\n",
      "\"./表达式与语义.ipynb\"\n",
      "\"./面向对象与语法特性.ipynb\"\n"
     ]
    }
   ],
   "source": [
    "#include <filesystem>\n",
    "#include <iostream>\n",
    "\n",
    "{\n",
    "    namespace fs = std::filesystem;\n",
    "    try {\n",
    "        for (const auto& entry : fs::directory_iterator(\".\")) {\n",
    "            std::cout << entry.path() << '\\n';\n",
    "        }\n",
    "    } catch (const fs::filesystem_error& e) {\n",
    "        std::cerr << \"Error: \" << e.what() << '\\n';\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::chrono` 时间点与时间段\n",
    "\n",
    "- **时间段 (`duration`)**：表示时间长度，模板参数为表示类型与 period；如 `std::chrono::seconds`.\n",
    "- **时间点 (`time_point`)**：基于时钟（如 `system_clock`, `steady_clock`, `high_resolution_clock`）的绝对时间。\n",
    "- C++17 增加别名如 `std::chrono::literals`、`std::chrono::milliseconds` 用户字面量（`100ms`）等，并完善 `std::chrono::duration_cast`、`floor`, `ceil`, `round`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Elapsed: 0ms\n"
     ]
    }
   ],
   "source": [
    "#include <chrono>\n",
    "#include <iostream>\n",
    "\n",
    "{\n",
    "    using namespace std::chrono;\n",
    "    auto start = steady_clock::now();\n",
    "    // ... work ...\n",
    "    auto end = steady_clock::now();\n",
    "    auto elapsed = duration_cast<milliseconds>(end - start);\n",
    "    std::cout << \"Elapsed: \" << elapsed.count() << \"ms\\n\";\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::array` vs C 风格数组\n",
    "\n",
    "- `std::array<T, N>` 是固定大小的容器，封装在类中，支持 STL 接口（迭代器、`size()`、`fill()` 等）。\n",
    "- 更安全：可拷贝赋值，带范围检查（配合 `at()`）。\n",
    "- 与 C 数组不同，`std::array` 可与泛型算法直接配合，类型可推导 `std::array<int, 3>`。\n",
    "- 应优先选择 `std::array`，除非必须与低级 API 交互或需要编译期常量表达式的裸数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 \n",
      "size = 3\n"
     ]
    }
   ],
   "source": [
    "#include <array>\n",
    "#include <iostream>\n",
    "\n",
    "{\n",
    "    std::array<int, 3> arr{1, 2, 3};\n",
    "    for (auto v : arr) std::cout << v << ' ';\n",
    "    std::cout << \"\\nsize = \" << arr.size() << '\\n';\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::allocator` 的角色 & 自定义用途\n",
    "\n",
    "- 标准容器通过 allocator 抽象内存管理（分配、销毁）。\n",
    "- 典型自定义用途：\n",
    "  - 从对象池 / 共享内存 / 自定义 Arena 分配。\n",
    "  - 限制内存对齐方式或监测内存使用。\n",
    "  - 嵌入式/实时系统中减少 `new/delete` 影响。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 一次性向系统申请一大块连续内存，称为一个“arena”（竞技场、区域）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "template <typename T>\n",
    "struct LoggingAllocator {\n",
    "    using value_type = T;\n",
    "    T* allocate(std::size_t n) {\n",
    "        std::cout << \"Alloc \" << n << '\\n';\n",
    "        return static_cast<T*>(::operator new(n * sizeof(T)));\n",
    "    }\n",
    "    void deallocate(T* p, std::size_t) noexcept {\n",
    "        std::cout << \"Dealloc\\n\";\n",
    "        ::operator delete(p);\n",
    "    }\n",
    "};"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| 特性维度       | `std::allocator`                                             | `std::pmr::polymorphic_allocator` / `pmr` 体系               |\n",
    "| -------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |\n",
    "| 引入版本       | C++98 标准就存在                                             | C++17 新增 `<memory_resource>`                               |\n",
    "| 设计理念       | 编译期确定的模板分配器，接口固定                             | 运行时多态的内存资源框架，可替换策略                         |\n",
    "| 默认行为       | 通常直接调用全局 `operator new/delete`                       | 通过内部指针指向某个 `memory_resource`，默认使用 `std::pmr::new_delete_resource()` |\n",
    "| 与容器结合方式 | `std::vector<T, std::allocator<T>>` (默认)                   | `std::pmr::vector<T>` 使用 `pmr::polymorphic_allocator`      |\n",
    "| 自定义策略     | 需编写符合分配器概念的模板类，较繁琐                         | 只需提供自定义 `memory_resource`（如 arena、池），运行时注入 |\n",
    "| 生命周期控制   | 与容器同 lifespan；无法在运行时动态切换                      | 同一个容器可在构造时指定不同 resource；多个容器共享资源更方便 |\n",
    "| 使用场景       | 常规用途，简单、无需特殊内存管理的代码                       | 需要局部内存池、arena、短期对象批量分配、可控资源管理的模块  |\n",
    "| 兼容性         | 所有标准容器默认支持                                         | 提供 `pmr` 版本容器（如 `pmr::vector`），可与传统容器并存    |\n",
    "| 迁移成本       | 零（默认即使用）                                             | 需包含 `<memory_resource>` 并理解 `memory_resource` 生命周期 |\n",
    "| 是否相互替代   | 否，`std::allocator` 仍适用于大部分场景；`pmr` 只是提供更多可选策略 | 同左                                                         |\n",
    "\n",
    "结论：`pmr` 并未取代 `std::allocator`，而是在需要更灵活、更可控的内存管理策略时提供额外工具。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::sort` 的复杂度与自定义排序\n",
    "\n",
    "- **复杂度**：平均 O(n log n)，最坏 O(n log n)（实现要求，用 IntroSort）。\n",
    "- **要求**：迭代器需是随机访问迭代器（如 `vector`, `deque`，`array`）。\n",
    "- 对自定义对象排序需提供比较器或重载 `<`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "#include <algorithm>\n",
    "#include <vector>\n",
    "\n",
    "struct Person {\n",
    "    std::string name;\n",
    "    int age;\n",
    "};\n",
    "\n",
    "int main() {\n",
    "    std::vector<Person> v{{\"Alice\", 30}, {\"Bob\", 25}};\n",
    "    std::sort(v.begin(), v.end(), [](const Person& a, const Person& b) {\n",
    "        return a.age < b.age;\n",
    "    });\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::transform` / `std::accumulate` / `std::reduce`（C++17）\n",
    "\n",
    "| 算法              | 功能                                                         | 特点                    |\n",
    "| ----------------- | ------------------------------------------------------------ | ----------------------- |\n",
    "| `std::transform`  | 对输入范围应用函数，输出到另一范围或原地                     | 元素级映射，可一元/二元 |\n",
    "| `std::accumulate` | 顺序折叠（线性扫描），初值 seed                              | 保序，适合串行          |\n",
    "| `std::reduce`     | 类似 accumulate，但可并行（需 Execution Policy），不保证顺序 | 要求操作可交换 + 结合   |"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Squared: 1 4 9 16 25 \n",
      "Sum of squares (accumulate): 55\n",
      "Sum of squares (reduce, parallel): 55\n",
      "Sum of squares (reduce, sequential): 55\n"
     ]
    }
   ],
   "source": [
    "#pragma cling load(\"tbb\")\n",
    "\n",
    "#include <algorithm>\n",
    "#include <execution>\n",
    "#include <iostream>\n",
    "#include <numeric>\n",
    "#include <vector>\n",
    "\n",
    "{\n",
    "    std::vector<int> data{1, 2, 3, 4, 5};\n",
    "\n",
    "    // 1) std::transform：对每个元素平方，结果写入另一容器\n",
    "    std::vector<int> squared(data.size());\n",
    "    std::transform(data.begin(), data.end(), squared.begin(),\n",
    "                   [](int x) { return x * x; });\n",
    "\n",
    "    std::cout << \"Squared: \";\n",
    "    for (int x : squared) std::cout << x << ' ';\n",
    "    std::cout << '\\n';\n",
    "\n",
    "    // 2) std::accumulate：顺序折叠（串行），计算平方和\n",
    "    int sum_sq = std::accumulate(squared.begin(), squared.end(), 0);\n",
    "    std::cout << \"Sum of squares (accumulate): \" << sum_sq << '\\n';\n",
    "\n",
    "    // 3) std::reduce：可并行的折叠（执行策略），这里用并行策略\n",
    "    int sum_par = std::reduce(std::execution::par,\n",
    "                              squared.begin(), squared.end(), 0);\n",
    "    std::cout << \"Sum of squares (reduce, parallel): \" << sum_par << '\\n';\n",
    "\n",
    "    // reduce 也可以无执行策略（默认 sequential）\n",
    "    int sum_seq = std::reduce(squared.begin(), squared.end(), 0);\n",
    "    std::cout << \"Sum of squares (reduce, sequential): \" << sum_seq << '\\n';\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `std::string` 小字符串优化（SSO）\n",
    "\n",
    "- 多数实现会在 `std::string` 对象内部留一小块缓冲（如 15 字节）存放短字符串，避免动态分配。\n",
    "- 原理：利用对象本身存储小段数据 + 长度 + 终止符。\n",
    "- **可能失效的情况**：\n",
    "  - 字符串长度超过实现的 SSO 容量。\n",
    "  - 移动到旧 ABI/自定义 allocator 时可能禁用。\n",
    "  - 某些操作(如 `shrink_to_fit`、`reserve`)可能强制分配。\n",
    "\n",
    "**注意**：SSO 不是标准硬性保证，依赖具体实现，但现代主流库（libstdc++、libc++、MSVC）一般都支持。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> `shrink_to_fit` 是部分标准容器（如 `std::vector`, `std::string`, `std::deque`, `std::basic_string_view` 没有）提供的成员函数，用于**请求**释放多余容量，使 `capacity()` ≈ `size()`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# inline 变量\n",
    "\n",
    "- 解决多翻译单元中定义全局变量的一致性问题（过去需要 `extern` 声明 + 单一定义）。\n",
    "- Header-only 库可直接写 `inline constexpr Foo foo{...};`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `constexpr if`\n",
    "\n",
    "- 未被选择的分支**不会实例化**，因此可在模板中书写不适用于某些类型的代码而不报错。\n",
    "- 减少 SFINAE，改善编译时间，但过度嵌套仍会影响编译速度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "// 无需 `enable_if` 特化，逻辑集中。\n",
    "\n",
    "template<class T>\n",
    "void serialize(T const& v, Writer& w) {\n",
    "    if constexpr (std::is_integral_v<T>)\n",
    "        w.write_int(v);\n",
    "    else if constexpr (std::is_same_v<T, std::string>)\n",
    "        w.write_string(v);\n",
    "    else\n",
    "        static_assert(dependent_false<T>, \"Unsupported type\");\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `constexpr if` 替代 `enable_if` "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `[[nodiscard]]`\n",
    "\n",
    "- 标记函数返回值必须使用，否则编译器警告。防止忽略重要结果（错误码、`std::unique_ptr::release()`）。\n",
    "- 适用于操作结果、资源句柄、危险 API。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `[[maybe_unused]]` / `[[fallthrough]]`\n",
    "\n",
    "- `[[maybe_unused]]`: 抑制未使用变量/函数警告（条件编译时很有用）。\n",
    "- `[[fallthrough]]`: 显式标记 switch 中的“有意落空”，避免警告。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "switch(x) {\n",
    "  case 1: do_something();\n",
    "          [[fallthrough]];\n",
    "  case 2: do_other();\n",
    "          break;\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Copy elision / RVO / NRVO\n",
    "\n",
    "- **Copy elision**：编译器省略临时对象拷贝。\n",
    "- **RVO**：return value optimization（直接在调用者内构造返回对象）。\n",
    "- **NRVO**：named RVO，对具名局部变量生效。\n",
    "- C++17 保证在某些场景下必须消除拷贝（临时直接初始化返回值）。若无强制要求，编译器可拒绝（需遵守标准约束，如返回分支不一致可能阻止 NRVO）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 构造/析构中调用虚函数的风险\n",
    "\n",
    "- 在构造/析构期间，对象尚未成为/不再是派生类型，调用虚函数只会调用当前层实现，可能缺失派生层逻辑。建议改用非虚函数或延迟到 `init()`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 动态派发 vs 静态派发\n",
    "\n",
    "- **Dynamic dispatch**：运行时通过虚表，开销较大。\n",
    "- **Static dispatch**：编译期决定（模板、`if constexpr`、标签派发）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "template <typename T>\n",
    "void process(T&& t) {\n",
    "    if constexpr (std::is_integral_v<std::decay_t<T>>) { ... }\n",
    "    else { ... }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **`std::pmr` 解决什么痛点？如何自定义资源？**\n",
    "\n",
    "- 解决自定义分配器语法繁重问题，提供运行时选择内存资源。\n",
    "- 自定义：派生 `std::pmr::memory_resource`，实现 `do_allocate/deallocate/do_is_equal`，可实现池化、arena、共享资源"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **实时系统控制内存分配抖动**\n",
    "\n",
    "- 预分配、对象池、`pmr::monotonic_buffer_resource`，禁用动态分配或限制在初始化阶段。\n",
    "- 锁定内存（mlock），避免页面换入换出；使用 lock-free ring buffer。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **性能循环与 `restrict` / `[[gnu::always_inline]]`**\n",
    "\n",
    "- `restrict`（GCC/Clang扩展）告知指针无别名，提高向量化概率。\n",
    "- `[[gnu::always_inline]]` 强制内联关键函数，减少调度开销。需权衡可读性与二进制大小。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **`std::launder` 用途**\n",
    "\n",
    "- 解决通过 placement new 在同一存储重建对象后，旧指针未定义的问题。\n",
    "- 使用："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "auto ptr = new(storage) T(...);\n",
    "T* safe = std::launder(reinterpret_cast<T*>(storage));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **`std::invoke` 作用**\n",
    "\n",
    "- 统一调用可调用对象（函数、成员函数指针、函数对象）。\n",
    "- 通用包装器："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "template<class F, class... Args>\n",
    "decltype(auto) call(F&& f, Args&&... args) {\n",
    "    return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **逐步引入 `std::string_view`**\n",
    "\n",
    "- 先在新接口返回 `string_view` 而非 `const std::string&`；保持实参生命周期（常用 `span`/`string_view` 仅作读）。\n",
    "- 审查所有调用点确保延用的字符串存续，即避免传临时 `std::string_view` 脱离作用域。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **`steady_clock` vs `system_clock`**\n",
    "\n",
    "- `system_clock` 可被手动调整（NTP），不保证单调；\n",
    "- `steady_clock` 单调递增适合性能计时。测性能使用 `steady_clock` 以避免时间跳变。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **`std::variant` 状态机**\n",
    "\n",
    "- 使用 `std::visit` 驱动状态转移："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "cpp"
    }
   },
   "outputs": [],
   "source": [
    "using State = std::variant<StateA, StateB>;\n",
    "State step(State s, Event e) {\n",
    "    return std::visit([&](auto& st){ return st.handle(e); }, s);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意递归类型需 `std::monostate` 或 `std::unique_ptr` 包装，避免 variant 过大。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **零成本抽象理念示例**\n",
    "\n",
    "- 如数据流管线使用 `std::span` + `constexpr` 策略，编译期内联展开；通过 benchmark 证明与手写循环相同性能。\n",
    "- 展示汇编或基准结果，验证无额外分配/虚调用。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
